package com.lovo.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lovo.common.bean.CommodityBean;
import com.lovo.common.bean.CommoditySnapshotBean;
import com.lovo.common.bean.OrderBean;
import com.lovo.common.bean.OrderCommodityBean;
import com.lovo.common.result.GlobalHandleException;
import com.lovo.common.result.Result;
import com.lovo.common.result.ResultCode;
import com.lovo.common.util.RedisUtil;
import com.lovo.order.dao.IOrderDAO;
import com.lovo.order.service.ICommodityService;
import com.lovo.order.service.IOrderCommodityService;
import com.lovo.order.service.IOrderService;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author bdk
 * @since 2021-03-10
 */
@Service
@GlobalTransactional(rollbackFor = Throwable.class)
public class OrderServiceImpl extends ServiceImpl<IOrderDAO, OrderBean> implements IOrderService {

    @Resource
    private IOrderDAO orderDAO;
    @Resource
    private IOrderCommodityService orderCommodityService;
    @Resource
    private ICommodityService commodityService;
    @Resource
    private RedisUtil redisUtil;
//    @Resource
//    private RestTemplate restTemplate;
    @Resource
    private DiscoveryClient discoveryClient;
    private String url = "http://shop-commodity";

    @Override
    public void buy(Long userInfoId, Long commId) throws GlobalHandleException, InvocationTargetException, IllegalAccessException {
//        ServiceInstance serviceInstance = discoveryClient.getInstances("shop-commodity").get(0);
//        url = "http://"+serviceInstance.getHost() + ":" + serviceInstance.getPort();
        CommodityBean commodityBean = new CommodityBean();
        if(redisUtil.hasKey(commId.toString())){
            commodityBean = (CommodityBean) redisUtil.get(commId.toString());

        }else{
//            commodityBean = commodityService.getById(commId);
//           Result result =  restTemplate.getForObject(url+"/commodities/"+commId, Result.class);
            Result result  = commodityService.getCommodityById(commId);
//           commodityBean = (CommodityBean) result.getData();
            BeanUtils.populate(commodityBean, (Map<String,Object>) result.getData());
//            System.out.println("commodityBean"+commodityBean);
        }
        if(commodityBean.getCommStock() <= 0){
            throw new GlobalHandleException(ResultCode.COMMODITY_NOT_ENOUGH);
        }
        // 减少库存
        commodityBean.setCommStock(commodityBean.getCommStock() - 1);
        redisUtil.set(commId.toString(),commodityBean);

        CommoditySnapshotBean commoditySnapshotBean = new CommoditySnapshotBean();
        commoditySnapshotBean.setCommId(commodityBean.getCommId());
        commoditySnapshotBean.setCommName(commodityBean.getCommName());
        commoditySnapshotBean.setCommImg(commodityBean.getCommImg());
        commoditySnapshotBean.setCommPrice(commodityBean.getCommPrice());

//        commoditySnapshotService.save(commoditySnapshotBean);
//        restTemplate.postForObject(url + "/commoditySnapshots",commoditySnapshotBean,Result.class);
        commodityService.addCommoditySnapshot(commoditySnapshotBean);
        String orderId = redisUtil.generateOrderId();
        OrderBean orderBean = new OrderBean();
        orderBean.setUserId(userInfoId);
        orderBean.setOrderId(orderId);
        orderBean.setCreateTime(LocalDateTime.now());
        orderBean.setStatus(0);
        orderDAO.insert(orderBean);

        OrderCommodityBean orderCommodityBean = new OrderCommodityBean();
        orderCommodityBean.setCommSnapshotId(commoditySnapshotBean.getCommSnapshotId());
        orderCommodityBean.setOrderId(orderId);
        orderCommodityBean.setCount(1);
        orderCommodityService.save(orderCommodityBean);


    }

    /**
     * 秒杀下单
     * @param userInfoId
     * @param commId
     */
    @Override
    public void seckillBuy(Long userInfoId, Long commId) throws GlobalHandleException, InvocationTargetException, IllegalAccessException {
        CommodityBean commodityBean = new CommodityBean();
        // 判断缓存当中是否存在该商品，如果不存在则从数据库中查询并放入缓存
        if(redisUtil.hasKey(commId.toString())){
            commodityBean = (CommodityBean) redisUtil.get(commId.toString());

        }else{
            Result result  = commodityService.getCommodityById(commId);
            BeanUtils.populate(commodityBean, (Map<String,Object>) result.getData());
        }
        // 判断库存是否充足，如果库存不足则抢购失败
        if(commodityBean.getCommStock() <= 0){
            throw new GlobalHandleException(ResultCode.COMMODITY_NOT_ENOUGH);
        }
        // 在缓存中减少库存
        commodityBean.setCommStock(commodityBean.getCommStock() - 1);
        redisUtil.set(commId.toString(),commodityBean);

        // 增加商品快照信息
        CommoditySnapshotBean commoditySnapshotBean = new CommoditySnapshotBean();
        commoditySnapshotBean.setCommId(commodityBean.getCommId());
        commoditySnapshotBean.setCommName(commodityBean.getCommName());
        commoditySnapshotBean.setCommImg(commodityBean.getCommImg());
        commoditySnapshotBean.setCommPrice(commodityBean.getCommPrice());
        Result commoditySnapshotResult = commodityService.addCommoditySnapshot(commoditySnapshotBean);
        BeanUtils.populate(commoditySnapshotBean, (Map<String,Object>) commoditySnapshotResult.getData());

        // 增加订单
        String orderId = redisUtil.generateOrderId();
        OrderBean orderBean = new OrderBean();
        orderBean.setUserId(userInfoId);
        orderBean.setOrderId(orderId);
        orderBean.setCreateTime(LocalDateTime.now());
        orderBean.setStatus(0);
        orderBean.setCommId(commId);
        orderDAO.insert(orderBean);

//        int a = 100 / 0;

        // 创建订单和商品快照的中间信息
        OrderCommodityBean orderCommodityBean = new OrderCommodityBean();
        orderCommodityBean.setCommSnapshotId(commoditySnapshotBean.getCommSnapshotId());
        orderCommodityBean.setOrderId(orderId);
        orderCommodityBean.setCount(1);
        orderCommodityService.save(orderCommodityBean);

        // 将订单信息放入缓存
        redisUtil.hset("seckillOrder",orderId,orderBean);
        redisUtil.hset("seckillUser",userInfoId.toString(),orderId);
    }

    @Override
    public void updateStatus(String orderId,int status) {
        OrderBean orderBean = orderDAO.selectById(orderId);
        orderBean.setStatus(status);
        orderDAO.updateById(orderBean);
    }
}
